<script>
import { ref, computed, onMounted } from "vue";

export default {
  setup() {
    const container = ref(null); // 容器元素
    const scrollTop = ref(0); // 滚动位置
    const itemHeight = 50; // 每项高度
    const totalItems = 10000000; // 总项数
    const containerHeight = window.innerHeight; // 容器高度

    // 生成模拟数据
    const items = Array.from({ length: totalItems }, (_, i) => ({
      id: i,
      content: `Item ${i}`,
    }));

    // 计算总高度
    const totalHeight = computed(() => items.length * itemHeight);

    // 计算可视区域的起始和结束索引
    const startIndex = computed(() => Math.floor(scrollTop.value / itemHeight));
    const endIndex = computed(() =>
      Math.min(
        startIndex.value + Math.ceil(containerHeight / itemHeight),
        items.length
      )
    );

    // 计算可视区域内的项及其偏移量
    const visibleItems = computed(() =>
      items.slice(startIndex.value, endIndex.value).map((item, index) => ({
        ...item,
        offset: (startIndex.value + index) * itemHeight,
      }))
    );

    // 处理滚动事件
    const handleScroll = () => {
      scrollTop.value = container.value.scrollTop;
    };

    onMounted(() => {
      container.value.style.height = `${containerHeight}px`;
    });

    return {
      container,
      scrollTop,
      itemHeight,
      totalHeight,
      visibleItems,
      handleScroll,
    };
  },
};
</script>
<template>
  <div class="virtual-list" @scroll="handleScroll" ref="container">
    <div class="list" :style="{ height: `${totalHeight}px` }">
      <div
        v-for="item in visibleItems"
        :key="item.id"
        class="list-item"
        :style="{
          height: `${itemHeight}px`,
          transform: `translateY(${item.offset}px)`,
        }"
      >
        {{ item.content }}
      </div>
    </div>
  </div>
</template>

<style>
.virtual-list {
  overflow-y: auto;
}

.list {
  position: relative;
}

.list-item {
  position: absolute;
  width: 100%;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
}
</style>
